package com.encrypt;

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;

/**
 * Created by huangyugen on 2019/04/29
 * DES算法漏洞加速了对称加密算法的改进，产生了DESede算法，但是其算法低效的加密实现和较慢的处理速度
 * 仍不满足需求，所以AES加密算法出现
 **/
public abstract class AESCoder {

    /**
     * 密钥算法
     */
    public static final String KEY_ALGORITHEM = "AES";

    /**
     * 加密/解密算法/工作模式/填充方式
     */
    public static final String CIPHER_ALGORITHEM = "AES/ECB/PKCS5Padding";

    /**
     * 转换密钥
     * @param key 二进制密钥
     * @return 密钥
     * @throws Exception
     */
    private static Key toKey(byte[] key)throws Exception{
        //实例化AES密钥材料
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, KEY_ALGORITHEM);
        return secretKeySpec;
    }

    /**
     * 解密
     * @param data 待解密数据
     * @param key 密钥
     * @return
     * @throws Exception
     */
    public static byte[] decode(byte[] data,byte[] key)throws Exception{
        //还原密钥
        Key k = toKey(key);
        //实例化
        Cipher instance = Cipher.getInstance(CIPHER_ALGORITHEM);
        //初始化，设置解密方式
        instance.init(Cipher.DECRYPT_MODE,k);

        return instance.doFinal(data);
    }

    /**
     * 加密
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] encode(byte[] data,byte[] key)throws Exception{
        //还原密钥
        Key k = toKey(key);
        //实例化
        Cipher instance = Cipher.getInstance(CIPHER_ALGORITHEM);
        //初始化，设置加密方式
        instance.init(Cipher.ENCRYPT_MODE,k);

        return instance.doFinal(data);
    }

    public static byte[] initKey()throws Exception{
        KeyGenerator instance = KeyGenerator.getInstance(KEY_ALGORITHEM);

        //AES要求密钥长度128 192或者256
        instance.init(256);
        //生成私密密钥，返回二进制密钥
        SecretKey secretKey = instance.generateKey();
        return secretKey.getEncoded();
    }

    public static void main(String[] args) throws Exception {
        String inputStr = "AES";
        byte[] bytes = inputStr.getBytes();
        System.out.println("【原文】："+inputStr);
        //初始化密钥
        byte[] key = initKey();
        System.out.println("【密钥】："+ Base64.encode(key));
        //加密
        byte[] encode = DESCoder.encode(bytes, key);
        System.out.println("【加密】："+Base64.encode(encode));
        //解密
        byte[] decode = DESCoder.decode(encode, key);
        System.out.println("【解密】："+new String(decode));
    }
}
